Equipe 03
Eugène Dagan, Adrien Bacon, Léo Martin, Adam Meghith, Raphaël Linard et Eric Jouslin de Noray
Une célèbre agence d’espionnage a vécu des heures sombres ces dernières semaines. À plusieurs reprises, le matériel mis à disposition sur le terrain pour leurs agents a été détourné. Pour résoudre ce problème, l’agent R propose un prototype de coffre-fort nouvelle génération avec des mécanismes d’authentification plus efficaces.
Pour faciliter la production, un prototype rudimentaire est envisagé à l’aide d’une carte électronique de type Arduino et de composants simples comme des LEDs. L’agent R a rapidement produit un schéma de l’environnement de tests :

Il propose ensuite de doter chaque agent d’une carte électronique avec un numéro (CARD_ID) unique que lui seul connaîtra. En fonction de ce numéro, une série de 4 interrupteurs devra être positionnée avant d’insérer la carte pour activer le système d’authentification. Une fois la carte inséré une combinaison de résistances allumés sera formé et une tension spécifique pour chacun des 8 modèles de carte sera obtenu.
Dans le précédent livrable nous avions fournis l’intégralité des circuits électriques. Dans cette partie nous nous intéresserons tout particulièrement à l’aspect sécurité de notre coffre. Effectivement, nous avons dû créer le système de vérification de l’identité de la personne désireuse d’accéder au coffre.
Lien du Tinkercad :
Code Arduino MA1 :
int pinAnalogique = A0; //broche analogique pour lire la tention
float tension = 0; //variable pour stocker latension lue
const int ledPins[4] = {4, 5, 6, 7}; //les différentes broches des LED
const int buttonPins[5] = {8, 9, 10, 11, 12}; //les différentes broches des boutons
int sequence[4] = {0, 1, 2, 3}; //ordre d'appui initial (sequence)
int currentStep = 0; //étape actuelle de la séquence
int newSequence[4]; //stockage de la nouvelle séquence
bool lastButtonStates[4] = {HIGH, HIGH, HIGH, HIGH}; //états initiaux des bouttons
bool errorOccurred = false; //indicateur d'erreur
bool sequenceComplete = false; //indicateur de séquence complète
bool configMode = false; //indicateur du mode Configuration
int configStep = 0; //étape actuelle de la Configuration
int errorCount = 0; //compteur d'erreur
bool lockout = false; //indicateur de bloquage d'essais
void setup(){
Serial.begin(9600); //initialiser la communication
for (int i = 0; i < 4; i++){
pinMode(ledPins[i], OUTPUT); //configurer chaque LED en sorties
digitalWrite(ledPins[i], HIGH); //éteindre chaque LED au démarage
pinMode(buttonPins[i], INPUT_PULLUP); //configurer chaque bouton en entrée
}
}
void loop(){
int valeurLue = analogRead(pinAnalogique); //lire la valeur analogique
tension = valeurLue * (5.0 / 1023.0); //définir cette valeur en une tension
Serial.print("Tension mesuree: ");
Serial.print(tension);
Serial.println(" V");
delay(1000);
if (tension >= 1 && tension <= 1.29){ //verifier si la tension se trouve dans l'intervalle
Securite1(); //lancer le système de sécurité numéro 1
}
if (tension >= 1.30 && tension <= 2.05){ //verifier si la tension se trouve dans l'intervalle
Securite2(); //lancer le système de sécurité numéro 2
}
if (tension >= 2.06 && tension <= 2.46){ //verifier si la tension se trouve dans l'intervalle
Securite3(); //lancer le système de sécurité numéro 3
}
if (tension >= 2.47 && tension <= 2.87){ //verifier si la tension se trouve dans l'intervalle
Securite4(); //lancer le système de sécurité numéro 4
}
if (tension >= 2.88 && tension <= 3.05){ //verifier si la tension se trouve dans l'intervalle
Securite5(); //lancer le système de sécurité numéro 5
}
if (tension >= 3.06 && tension <= 3.21){ //verifier si la tension se trouve dans l'intervalle
Securite5(); //lancer le système de sécurité numéro 5
}
if (tension >= 3.22 && tension <= 3.49){ //verifier si la tension se trouve dans l'intervalle
Securite2(); //lancer le système de sécurité numéro 2
}
if (tension >= 3.50 && tension <= 3.71){ //verifier si la tension se trouve dans l'intervalle
Securite4(); //lancer le système de sécurité numéro 4
}
}
void MA2(){
if (lockout){
delay(30000); //attendre 30 secondes
signalRetry(); //signal lumineux pour montrer que l'on peut réessayer
resetSequence(); //Remettre l'étape actuelle de la séaquence à 0
lockout = false; //Réinitialiser l'indicateur de bloquage d'essais
}
if (errorOccurred){
errorOccurred = false; //Réinitialiser l'indicateur d'erreur
resetSequence(); //Remettre l'étape actuelle de la séaquence à 0
}
if (sequenceComplete){
blinkLEDsInSequence(); //signal lumineux de réussite
enterConfigMode(); //entrer dans le mode configuration
return;
}
if (configMode){
configureSequence(); //configuration de la séquence
return;
}
for (int i = 0; i < 5; i++){
bool buttonState = digitalRead(buttonPins[i]); //lecture d'un changement d'état des boutons poussoirs
if (buttonState == LOW && lastButtonStates[i] == HIGH){ //si changement d'état de l'un des boutons
if (i == sequence[currentStep]){ //si le bouton appuyer est celui correspondant à l'étape de la séquence
digitalWrite(ledPins[currentStep], LOW); //allumer la LED corespondant au nombre de l'étape
currentStep++; //passer à l'étape suivante de la séquence
} else{
errorCount++; //Rajouter +1 au compteur d'erreur
indicateError();
errorOccurred = true;
if (errorCount >= 4){ //si le compteur d'erreur est à 4 alors il lance le bloquage d'essais pendant 30 secondes
lockout = true;
}
return;
}
delay(50);
if (currentStep >= 4){ //si l'indicateur d'étape est supérieur ou égal à 4 alors dire que la sequence est complété
sequenceComplete = true;
return;
}
}
lastButtonStates[i] = buttonState;
}
}
void indicateError(){ //Faire clignoter 3 fois toutes les LED pour montrer une erreur
for (int j = 0; j < 3; j++){
for (int k = 0; k < 4; k++){
digitalWrite(ledPins[k], LOW);
}
delay(300);
for (int k = 0; k < 4; k++){
digitalWrite(ledPins[k], HIGH);
}
delay(300);
}
}
void resetSequence(){ //Eteindre toutes les LED, remettre l'étape de config à 0, remmetre l'étape de la séquence de la config à 0
for (int j = 0; j < 4; j++){
digitalWrite(ledPins[j], HIGH);
}
currentStep = 0;
sequenceComplete = false;
configStep = 0;
}
void blinkLEDsInSequence(){ //Faire un signal lumineux 3 fois avec toutes les LED pour signaler une réussite
for(int repeat = 0; repeat < 3; repeat++){
for (int i = 0; i < 4; i++) {
digitalWrite(ledPins[i], LOW);
delay(200);
digitalWrite(ledPins[i], HIGH);
delay(200);
}
}
}
void enterConfigMode(){ //Entrer en mode configuration
configMode = true;
resetSequence();
}
void configureSequence(){ //Configuration de la nouvelle séquence
for(int i = 0; i < 5; i++){
bool buttonState = digitalRead(buttonPins[i]);
if(buttonState == LOW && lastButtonStates[i] == HIGH){
newSequence[configStep] = i;
digitalWrite(ledPins[configStep], LOW);
configStep++;
delay(300);
if(configStep >= 4){
applyNewSequence();
configMode = false;
}
}
lastButtonStates[i] = buttonState;
}
}
void applyNewSequence(){ //appliquer/remplacer l'ancienne séquence par la nouvelle
for(int i = 0; i < 4; i++){
sequence[i] = newSequence[i];
digitalWrite(ledPins[i], HIGH);
}
resetSequence();
}
void signalRetry(){ //Faire un signal lumineux avec les LED pour signifier que l'utilisateur peut réessayer
for(int i = 0; i < 6; i++){
for (int j = 0; j < 4; j++){
digitalWrite(ledPins[j], LOW);
}
delay(250);
for(int j = 0; j < 4; j++){
digitalWrite(ledPins[j], HIGH);
}
delay(250);
}
}
void MA1(){
const int totalQuestions = 3; //nombre total de questions
String questions[totalQuestions] = {
"Quand l'agence d'espionnage a t-elle etait cree ?", //question 1
"Comment s'appelle l'agence ?", //question 2
"Qui a cree l'entreprise ?" //question 3
};
String reponsesCorrectes[totalQuestions] = {
"1929", //réponse 1
"Secret Service", //réponse 2
"Adrien et Eric" //réponse 3
};
int questionActuelle = 0; //question actuelle
bool MA1right = false; //Faire une boucle MA1
Serial.println("Veuillez repondre a ces 3 questions pour prouvez votre identite");
delay(1500);
Serial.println(questions[questionActuelle]); //poser la première question
while(MA1right = true){
if(Serial.available() > 0){ //vérification de si il reste des réponses
String reponseUtilisateur = Serial.readString(); //lire la réponse de l'utilisateur
reponseUtilisateur.trim(); //supprimer les espaces
if(reponseUtilisateur == reponsesCorrectes[questionActuelle]){ //si la réponse est correct
Serial.println("Correct !");
delay(1500);
questionActuelle++; //passer à la question suivante
} else{ //sinon
Serial.println("Incorrect. Recommencons depuis le debut.");
delay(1500);
questionActuelle = 0; //renvoyer à la première question
}
if(questionActuelle < totalQuestions){ //verifier s'il reste des questions
Serial.println(questions[questionActuelle]); //si oui la poser
} else{
Serial.println("Premier test d'authentification reussi!"); //sinon alors réussite du programme
return;
}
}
}
}
void MA3(){ //système de vérification MA3
Serial.println("Veuillez presenter votre oeil devant la carte arduino");
delay(15000);
Serial.println("Votre oeil à été reconnue par la carte");
delay(5000);
}
void MA4(){ //système de vérification MA4
Serial.println("Veuillez presenter votre doigt devant la carte arduino");
delay(15000);
Serial.println("Votre doigt à été reconnue par la carte");
delay(5000);
}
void MA5(){ //système de vérification MA5
delay(1000);
}
void reussite(){ //indication de la réussite final
Serial.println("Vous avez reussi a passer tous les tests d'authentification.");
delay(1000);
Serial.println("Ouverture du coffre");
}
void Securite1(){ //niveau de sécurité 1
Serial.println("Carte reconnu, code bon");
MA1();
MA3();
reussite();
}
void Securite2(){ //niveau de sécurité 2
Serial.println("Carte reconnu, code bon");
MA1();
MA4();
reussite();
}
void Securite3(){ //niveau de sécurité 3
Serial.println("Carte reconnu, code bon");
MA2;
MA4;
reussite;
}
void Securite4(){ //niveau de sécurité 4
Serial.println("Carte reconnu, code bon");
MA1();
MA2();
MA3();
MA4();
reussite;
}
void Securite5(){ //niveau de sécurité 5
Serial.println("Carte reconnu, code bon");
MA1();
MA2();
MA3();
MA4();
MA5();
reussite;
}
Sortie :
Tension mesurée : ... V # Tension mesurée par l'arduino
Carte reconnu, code bon
# Exécution d'un niveau niveau de sécurité qui est défini par le calcule de la tension
Vous avez reussi a passer tous les tests d'authentification.
Ouverture du coffre
Mise en contexte
Les modèles correspondants à leurs tension ainsi que leur niveau de sécurité

MA1 : Authentification par questions/réponses
MA2 : Authentification par un code qui change au cours du temps (code via bouton poussoir)
MA3 : Scan rétinien
MA4 : Scan digital
MA5 : CardID
Nous précisons que les niveaux de sécurités associés à chaque modèle de carte est choisis de manière purement arbitraire. Dans le tableau ci-dessus les abréviations Ma 1,2,3,4 correspondent au vérification différentes que le coffre est capable de mettre en œuvre.
Par exemple le modèle 1 est associé avec le niveau de sécurité 1 qui comprend les vérification MA1 et MA3.
MA1
Cette vérification est un jeu de question réponse ou l’agent souhaitant accéder au coffre doit donner les bonnes réponses. Si celui-ci se trompe il doit recommencer du début son indentification par le coffre. On peut représenter cette vérification par un programme sous forme de logigramme (voir ci-dessous).
Code Arduino MA1 :
void MA1(){
const int totalQuestions = 3; //nombre total de questions
String questions[totalQuestions] = {
"Quand l'agence d'espionnage a t-elle etait cree ?", //question 1
"Comment s'appelle l'agence ?", //question 2
"Qui a cree l'entreprise ?" //question 3
};
String reponsesCorrectes[totalQuestions] = {
"1929", //réponse 1
"Secret Service", //réponse 2
"Adrien et Eric" //réponse 3
};
int questionActuelle = 0; //question actuelle
bool MA1right = false; //Faire une boucle MA1
Serial.println("Veuillez repondre a ces 3 questions pour prouvez votre identite");
delay(1500);
Serial.println(questions[questionActuelle]); //poser la première question
while(MA1right = true){
if(Serial.available() > 0){ //vérification de si il reste des réponses
String reponseUtilisateur = Serial.readString(); //lire la réponse de l'utilisateur
reponseUtilisateur.trim(); //supprimer les espaces
if(reponseUtilisateur == reponsesCorrectes[questionActuelle]){ //si la réponse est correct
Serial.println("Correct !");
delay(1500);
questionActuelle++; //passer à la question suivante
} else{ //sinon
Serial.println("Incorrect. Recommencons depuis le debut.");
delay(1500);
questionActuelle = 0; //renvoyer à la première question
}
if(questionActuelle < totalQuestions){ //verifier s'il reste des questions
Serial.println(questions[questionActuelle]); //si oui la poser
} else{
Serial.println("Premier test d'authentification reussi!"); //sinon alors réussite du programme
return;
}
}
}
}
Sortie :
Quand l'agence d'espionnage a t-elle etait cree ?
1929 # Réponse de l'utilisateur
Comment s'appelle l'agence ?
Secret Service # Réponse de l'utilisateur
Qui a cree l'entreprise ?
Adrien et Eric # Réponse de l'utilisateur
Premier test d'authentification reussi!
MA2
Cette seconde vérification est un digicode (code à 4 chiffres) que l’agent doit mettre afin de prouver son éligibilité, puis après la saisie du bon code l’agent doit changer ce code par celui-ci
Code Arduino MA2 :
void MA2(){
if (lockout){
delay(30000); //attendre 30 secondes
signalRetry(); //signal lumineux pour montrer que l'on peut réessayer
resetSequence(); //Remettre l'étape actuelle de la séaquence à 0
lockout = false; //Réinitialiser l'indicateur de bloquage d'essais
}
if (errorOccurred){
errorOccurred = false; //Réinitialiser l'indicateur d'erreur
resetSequence(); //Remettre l'étape actuelle de la séaquence à 0
}
if (sequenceComplete){
blinkLEDsInSequence(); //signal lumineux de réussite
enterConfigMode(); //entrer dans le mode configuration
return;
}
if (configMode){
configureSequence(); //configuration de la séquence
return;
}
for (int i = 0; i < 5; i++){
bool buttonState = digitalRead(buttonPins[i]); //lecture d'un changement d'état des boutons poussoirs
if (buttonState == LOW && lastButtonStates[i] == HIGH){ //si changement d'état de l'un des boutons
if (i == sequence[currentStep]){ //si le bouton appuyer est celui correspondant à l'étape de la séquence
digitalWrite(ledPins[currentStep], LOW); //allumer la LED corespondant au nombre de l'étape
currentStep++; //passer à l'étape suivante de la séquence
} else{
errorCount++; //Rajouter +1 au compteur d'erreur
indicateError();
errorOccurred = true;
if (errorCount >= 4){ //si le compteur d'erreur est à 4 alors il lance le bloquage d'essais pendant 30 secondes
lockout = true;
}
return;
}
delay(50);
if (currentStep >= 4){ //si l'indicateur d'étape est supérieur ou égal à 4 alors dire que la sequence est complété
sequenceComplete = true;
return;
}
}
lastButtonStates[i] = buttonState;
}
}
MA3
Code Arduino MA3 :
Cette troisième vérification vise à faire un scan rétinien à l’aide d’un booléen.
void MA3(){ //système de vérification MA3
Serial.println("Veuillez presenter votre oeil devant la carte arduino");
delay(15000);
Serial.println("Votre oeil a été reconnue par la carte");
delay(5000);
}
Sortie :
Veuillez presenter votre oeil devant la carte arduino
# Scan en cours
Votre oeil a été reconnue par la carte
MA4
Code Arduino MA4 :
Cette quatrième vérification est un deuxième scan cette fois-ci digital à l’aide d’un booléen également.
void MA4(){ //système de vérification MA4
Serial.println("Veuillez presenter votre doigt devant la carte arduino");
delay(15000);
Serial.println("Votre doigt a été reconnue par la carte");
delay(5000);
}
Sortie :
Veuillez presenter votre doigt devant la carte arduino
# Scan en cours
Votre doigt a été reconnue par la carte
MA5
Code Arduino MA5 :
Cette ultime vérification a pour objectif de confirmer l’identité d’une personne souhaitant accéder au coffre-fort Elle doit d saisir l’identifiant de sa carte pour prouver son éligibilité.
# Non terminé
void MA5(){ //système de vérification MA5
delay(1000);
}
En conclusion, nous n’avons pas réussi à faire fonctionner le montage complet du coffre mais les différents code des niveaux de sécurité fonctionnent, sauf pour le niveau 5 que nous n’avons pas terminé à temps. Puis nous ne sommes pas arrivé à calculer la tension voulue.